#include "lv_port_indev.h"
#include <lvgl.h>

#define LOG_LEVEL CONFIG_LOG_DEFAULT_LEVEL
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(indev_port);


static lv_indev_drv_t input_drv;
static lv_group_t *input_grp;
static uint8_t now_pressed, last_pressed;



static void input_read(struct _lv_indev_drv_t *indev_drv, lv_indev_data_t *data)
{
    // 给 lvgl 发送物理输入事件.
    if (now_pressed == USER_SW1) {

        data->key = LV_KEY_LEFT;
        data->state = LV_INDEV_STATE_PR;
        last_pressed = USER_SW1;

    } else if (now_pressed == USER_SW2) {

        data->key = LV_KEY_RIGHT;
        data->state = LV_INDEV_STATE_PR;
        last_pressed = USER_SW2;

    } else if (now_pressed == USER_SW3) {

        data->key = LV_KEY_UP;
        data->state = LV_INDEV_STATE_PR;
        last_pressed = USER_SW3;

    } else if (now_pressed == USER_SW4) {

        data->key = LV_KEY_DOWN;
        data->state = LV_INDEV_STATE_PR;
        last_pressed = USER_SW4;
        // Not used for now. TODO exit/back button.
    } else {

        if (last_pressed == 0xFF) {
            return;
        }

        data->state = LV_INDEV_STATE_REL;
        switch (last_pressed) {

            case USER_SW1:
                data->key = LV_KEY_LEFT;
                break;

            case USER_SW2:
                data->key = LV_KEY_RIGHT;
                break;

            case USER_SW3:
                data->key = LV_KEY_UP;
                break;

            case USER_SW4:
                data->key = LV_KEY_DOWN;
                break;

            default:
                break;
        }

        last_pressed = 0xFF;
    }
    
    now_pressed = 0;
}



/***
 * 不论是DFU模式还是普通模式下的按键触发回调
*/
static void button_changed(uint32_t button_state, uint32_t has_changed)
{
    const uint8_t key_list[4] = {USER_SW1, USER_SW2, USER_SW3, USER_SW4};
    uint32_t key_detecet = 0;

    for(uint32_t i = 0; i < sizeof(key_list); i++)
    {
        // 查找对应按键
        if (has_changed & key_list[i]) 
        {
            // 判断当前设备状态.
            key_detecet = button_state & key_list[i];
            if(key_detecet != 0)
            { 
                now_pressed |= key_list[i];
                // LOG_INF("Press %d", now_pressed);
            }
            else
            {
                now_pressed &= ~key_list[i];
                // LOG_INF("Depress %d", now_pressed);
            }
            break;
        }
    }
}




int lv_port_indev_init(void)
{
    lv_indev_t *indev;

    dk_buttons_init(button_changed);

    lv_indev_drv_init(&input_drv);
    input_drv.type = LV_INDEV_TYPE_KEYPAD;
    input_drv.read_cb = input_read;
    indev = lv_indev_drv_register(&input_drv);

    input_grp = lv_group_create();
    lv_indev_set_group(indev, input_grp);
    lv_group_set_default(input_grp);
    lv_group_set_wrap(input_grp, true);

    return 0;
}